// $Id: TacticaTururu.java,v 1.9 2007-04-12 00:03:51 raul Exp $
package futbol.tacticas.concursantes2007.TacticaTururu;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Vector;

import futbol.tacticas.Comando;
import futbol.tacticas.ComandoIrA;
import futbol.tacticas.ComandoPase;
import futbol.tacticas.ComandoTiroAPuerta;
import futbol.tacticas.SituacionJugadores;
import futbol.tacticas.concursantes.Tactica;
import futbol.tacticas.concursantes2007.TacticaTururu.Alineacion;
import futbol.tacticas.concursantes2007.TacticaTururu.Constantes;
import futbol.tacticas.concursantes2007.TacticaTururu.Defensa;
import futbol.tacticas.concursantes2007.TacticaTururu.Delantero;
import futbol.tacticas.concursantes2007.TacticaTururu.DistanciaIrBola;
import futbol.tacticas.concursantes2007.TacticaTururu.Entrenador;
import futbol.tacticas.concursantes2007.TacticaTururu.Fuerza;
import futbol.tacticas.concursantes2007.TacticaTururu.Genotipo;
import futbol.tacticas.concursantes2007.TacticaTururu.Jugador;
import futbol.tacticas.concursantes2007.TacticaTururu.Portero;


public class TacticaTururu implements Tactica {

    // ----------------------- //
    // ATRIBUTOS DE LA TACTICA //
    // ----------------------- //
    private Alineacion[] alineacion = new Alineacion[2];
    private Fuerza fuerza;

    private Genotipo genotipo;
    private int perdiendoGanando = Constantes.EMPATE_O_GANANDO;

    private Jugador[] jugador = new Jugador[Constantes.JUGADORES_EN_TERRENO];
    private Entrenador entrenador = new Entrenador();
    private int [] dorsalesDefensa;
    private int [] dorsalesMedioCampoAtras;
    private int [] dorsalesMedioCampoAlante;
    private int [] dorsalesDelantera;

	private int jugadoresDefensa;
	private int jugadoresMedioCampoAtras;
	private int jugadoresMedioCampoAlante;
	private int jugadoresDelantera;

	private int golesMios = 0, golesContrario = 0, nXBolaAnt = 0;

    // --------------------------- //
    // CONSTRUCTORES E INICIADORES //
    // --------------------------- //
    public TacticaTururu() {

    	genotipo = new Genotipo();

    	genotipo.setFuerza(new Fuerza ("7-4-6-7-7"));
    	genotipo.setAlineacionEmpateGanando(new Alineacion ("2-3-2-3"));
    	genotipo.setAlineacionPerdiendo(new Alineacion ("3-2-2-3"));
    	genotipo.setDistanciaEmpateGanando(new DistanciaIrBola ("1-5-7-4-2"));
    	genotipo.setDistanciaPerdiendo(new DistanciaIrBola ("9-8-8-7-2"));
    	genotipo.setPorteroBarreraPerdiendo(-150);
    	genotipo.setPorteroBarreraEmpateGanando(-155);
    	genotipo.setPorteroLateralPerdiendo(26);
    	genotipo.setPorteroLateralEmpateGanando(26);
    	genotipo.setPorteroFactorProximidadPerdiendo(9);
        genotipo.setPorteroFactorProximidadEmpateGanando(8);
        genotipo.setDefensaFactorProximidadPerdiendo(6);
        genotipo.setDefensaFactorProximidadEmpateGanando(6);
        genotipo.setDefensaTerminoProximidadPerdiendo(15);
        genotipo.setDefensaTerminoProximidadEmpateGanando(20);
        genotipo.setEntrenadorLineaDefensivaPerdiendo(-20);
        genotipo.setEntrenadorLineaDefensivaEmpateGanando(-20);
        genotipo.setEntrenadorDistanciaMinimaPasePerdiendo(20);
        genotipo.setEntrenadorDistanciaMinimaPaseEmpateGanando(25);

        alineacion[Constantes.EMPATE_O_GANANDO] = genotipo.getAlineacionEmpateGanando();
        alineacion[Constantes.PERDIENDO] = genotipo.getAlineacionPerdiendo();
        fuerza = genotipo.getFuerza();

        for (int i = 0; i < Constantes.JUGADORES_EN_TERRENO; i++)
        	jugador[i] = new Jugador(i);

        configurarNaturalezaJugadores();
    }

    private void configurarNaturalezaJugadores () {

        // se recupera la alineacion
    	jugador = genotipo.configurarJugadores(jugador, alineacion[perdiendoGanando], fuerza);

    	jugadoresDefensa = alineacion[perdiendoGanando].getAlineacion()[Constantes.LINEA_DEFENSIVA];
    	jugadoresMedioCampoAtras = alineacion[perdiendoGanando].getAlineacion()[Constantes.LINEA_CENTRO_CAMPO_ATRAS];
    	jugadoresMedioCampoAlante = alineacion[perdiendoGanando].getAlineacion()[Constantes.LINEA_CENTRO_CAMPO_ALANTE];
    	jugadoresDelantera = alineacion[perdiendoGanando].getAlineacion()[Constantes.LINEA_DELANTERA];

    	dorsalesDefensa = new int [jugadoresDefensa];
    	dorsalesMedioCampoAtras = new int [jugadoresMedioCampoAtras];
    	dorsalesMedioCampoAlante = new int [jugadoresMedioCampoAlante];
    	dorsalesDelantera = new int [jugadoresDelantera];

    	// exluimos al jugador 0 porque es el portero
    	jugador [0] = new Portero(0);
    	jugador [0].setDistanciaIrBola(genotipo.getDistancia()[perdiendoGanando].getDistanciaIrBola()[4]);
    	((Portero) jugador [0]).setBarrera(genotipo.getPorteroBarrera()[perdiendoGanando]);
    	((Portero) jugador [0]).setLateral(genotipo.getPorteroLateral()[perdiendoGanando]);
    	((Portero) jugador [0]).setFactorProximidad(genotipo.getPorteroFactorProximidad()[perdiendoGanando]);

    	int contadorJugadoresUbicados = 1;
    	for (int i = contadorJugadoresUbicados; i < contadorJugadoresUbicados + jugadoresDefensa; i++) {
    		jugador [i] = new Defensa (i);
    		jugador [i].setDistanciaIrBola(genotipo.getDistancia()[perdiendoGanando].getDistanciaIrBola()[Constantes.LINEA_DEFENSIVA]);
    		((Defensa) jugador[i]).setFactorProximidad(genotipo.getDefensaFactorProximidad()[perdiendoGanando]);
    		((Defensa) jugador[i]).setTerminoProximidad(genotipo.getDefensaTerminoProximidad()[perdiendoGanando]);
    		dorsalesDefensa [i - contadorJugadoresUbicados] = i;
    	}

    	contadorJugadoresUbicados += jugadoresDefensa;
    	for (int i = contadorJugadoresUbicados; i < contadorJugadoresUbicados + jugadoresMedioCampoAtras; i++) {
    		jugador [i] = new Defensa (i);
    		jugador [i].setDistanciaIrBola(genotipo.getDistancia()[perdiendoGanando].getDistanciaIrBola()[Constantes.LINEA_CENTRO_CAMPO_ATRAS]);
    		((Defensa) jugador[i]).setFactorProximidad(genotipo.getDefensaFactorProximidad()[perdiendoGanando]);
    		((Defensa) jugador[i]).setTerminoProximidad(genotipo.getDefensaTerminoProximidad()[perdiendoGanando]);
       		dorsalesMedioCampoAtras [i - contadorJugadoresUbicados] = i;
    	}

    	contadorJugadoresUbicados += jugadoresMedioCampoAtras;
    	for (int i = contadorJugadoresUbicados; i < contadorJugadoresUbicados + jugadoresMedioCampoAlante; i++) {
    		jugador [i] = new Delantero (i);
    		jugador [i].setDistanciaIrBola(genotipo.getDistancia()[perdiendoGanando].getDistanciaIrBola()[Constantes.LINEA_CENTRO_CAMPO_ALANTE]);
    		dorsalesMedioCampoAlante [i - contadorJugadoresUbicados] = i;
    	}

    	contadorJugadoresUbicados += jugadoresMedioCampoAlante;
    	for (int i = contadorJugadoresUbicados; i < contadorJugadoresUbicados + jugadoresDelantera; i++) {
    		jugador [i] = new Delantero (i);
    		jugador [i].setDistanciaIrBola(genotipo.getDistancia()[perdiendoGanando].getDistanciaIrBola()[Constantes.LINEA_DELANTERA]);
    		dorsalesDelantera [i - contadorJugadoresUbicados] = i;
    	}

    	entrenador.setDistanciaMinimaPase(genotipo.getEntrenadorDistanciaMinimaPase()[perdiendoGanando]);
    	entrenador.setLineaDefensiva(genotipo.getEntrenadorLineaDefensiva()[perdiendoGanando]);

    	jugador = genotipo.configurarJugadores(jugador, alineacion[perdiendoGanando], fuerza);

        // se facilita a los jugadores sus posiciones iniciales
        for (int i = 0; i < Constantes.JUGADORES_EN_TERRENO; i++) {
        	jugador[i].setOriginalX(jugador[i].getPosicionX());
        	jugador[i].setOriginalY(jugador[i].getPosicionY());
        }

    	entrenador.conoceEquipo(jugador, alineacion[perdiendoGanando], dorsalesDefensa, dorsalesMedioCampoAtras, dorsalesMedioCampoAlante, dorsalesDelantera);

    } // private void calcularDorsales ()

	public Vector<Comando> getComandos(SituacionJugadores sj) {
        Vector<Comando> comandos = new Vector<Comando>(11);
        Iterator iterador;

        int nXBola = (int) sj.getBola().getX();
        if (nXBolaAnt > 135 && nXBola < 40) {
        	golesMios++;
        	if (golesMios >= golesContrario) {

        		perdiendoGanando = Constantes.EMPATE_O_GANANDO;
        		configurarNaturalezaJugadores();
        	}
        }
        if (nXBolaAnt < -135 && nXBola > -40) {
        	golesContrario++;
        	if (golesMios < golesContrario) {

        		perdiendoGanando = Constantes.PERDIENDO;
        		configurarNaturalezaJugadores();
        	}
        }
        nXBolaAnt=nXBola;

        entrenador.setSituacionJugadores(sj);
        entrenador.asignaMarcajesDefensa();
        entrenador.asignaPases();

        // Posicionamiento por defecto
        for (int n = 0; n < Constantes.JUGADORES_EN_TERRENO; n++)
            comandos.add(new ComandoIrA(n, jugador[n].getPosicionX(), jugador[n].getPosicionY()));


        // Se insertan los comportamientos de los distintos jugadores
        iterador = defensa(sj).iterator();
        while (iterador.hasNext()) {
            comandos.add((Comando) iterador.next());
        }

        iterador = centroCampoAtras(sj).iterator();
        while (iterador.hasNext()) {
            comandos.add((Comando) iterador.next());
        }

        iterador = centroCampoAlante(sj).iterator();
        while (iterador.hasNext()) {
            comandos.add((Comando) iterador.next());
        }

        iterador = delantera(sj).iterator();
        while (iterador.hasNext()) {
            comandos.add((Comando) iterador.next());
        }

        iterador = portero(sj).iterator();
        while (iterador.hasNext()) {
            comandos.add((Comando) iterador.next());
        }

        return comandos;
    }

    private List defensa(SituacionJugadores sj) {
        List<Comando> miDefensa = new ArrayList<Comando>();
        int contadorJugadores = 1;
        int pase;

        for (int i = 0; i < dorsalesDefensa.length; i++) {
    		miDefensa.add(jugador[i + contadorJugadores].command(sj));
    		pase = jugador[i + contadorJugadores].getPase();
    		if (pase == Constantes.TIRO_A_PUERTA)
    			miDefensa.add(new ComandoTiroAPuerta(i + contadorJugadores, 0));
    		else
    			miDefensa.add(new ComandoPase(i + contadorJugadores, pase));

        }

        return miDefensa;
    }

    private List centroCampoAtras(SituacionJugadores sj) {
        List<Comando> miCentroCampoAtras = new ArrayList<Comando>();
        int contadorJugadores = 1 + jugadoresDefensa;
        int pase;

        for (int i = 0; i < dorsalesMedioCampoAtras.length; i++) {
        	miCentroCampoAtras.add(jugador[i + contadorJugadores].command(sj));
        	pase = jugador[i + contadorJugadores].getPase();
    		if (pase == Constantes.TIRO_A_PUERTA)
    			miCentroCampoAtras.add(new ComandoTiroAPuerta(i + contadorJugadores, 0));
    		else
    			miCentroCampoAtras.add(new ComandoPase(i + contadorJugadores, pase));

        }

        return miCentroCampoAtras;
    }

    private List centroCampoAlante(SituacionJugadores sj) {
        List<Comando> miCentroCampoAlante = new ArrayList<Comando>();
        int contadorJugadores = 1 + jugadoresDefensa + jugadoresMedioCampoAtras;
        int pase;

        for (int i = 0; i < dorsalesMedioCampoAlante.length; i++) {
        	miCentroCampoAlante.add(jugador[i + contadorJugadores].command(sj));
    		pase = jugador[i + contadorJugadores].getPase();
    		if (pase == Constantes.TIRO_A_PUERTA)
    			miCentroCampoAlante.add(new ComandoTiroAPuerta(i + contadorJugadores, 0));
    		else
    			miCentroCampoAlante.add(new ComandoPase(i + contadorJugadores, pase));

        }

        return miCentroCampoAlante;
    }

    private List delantera(SituacionJugadores sj) {
        List<Comando> miDelantera = new ArrayList<Comando>();
        int contadorJugadores = 1 + jugadoresDefensa + jugadoresMedioCampoAtras + jugadoresMedioCampoAlante;
        int descentrado = (Math.abs(new Random().nextInt()) % 30) - 15;

        for (int i = 0; i < dorsalesDelantera.length; i++) {
        	miDelantera.add(jugador[i + contadorJugadores].command(sj));
        	miDelantera.add(new ComandoTiroAPuerta(i + contadorJugadores, descentrado));
        }

        return miDelantera;
    }

    private List portero(SituacionJugadores sj) {

        List<Comando> miPortero = new ArrayList<Comando>();
        miPortero.add(jugador[0].command(sj));
		if ((jugador[0].getPase() == Constantes.TIRO_A_PUERTA) || (jugador[0].getPase() == 0)) {
			int descentrado = (Math.abs(new Random().nextInt()) % 30) - 15;
			miPortero.add(new ComandoTiroAPuerta(0, descentrado));
		} else
			miPortero.add(new ComandoPase(0, jugador[0].getPase()));

        return miPortero;
    }

    // ----------------------------------------------------------------------------------------------- //
    //                                      METODOS DEL JUEGO                                          //
    // ----------------------------------------------------------------------------------------------- //
    public Color getColor1() {
        return Color.BLUE;
    }

    public Color getColor2() {
        return Color.BLUE;
    }

    public Color getColorNumero() {
        return Color.WHITE;
    }

    public String getNombre() {
        return "F.C. Turur";
    }

	public int getFuerza(int n) {
		return jugador[n].getFuerza();
	}

	public int getXInicial(int n) {
		return jugador[n].getPosicionX();
	}

	public int getYInicial(int n) {
		return jugador[n].getPosicionY();
	}
} // public class TacticaTururu implements Tactica
